home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / XCMD libraries 960603 / xcmdBase.cp < prev    next >
Text File  |  1996-01-13  |  7KB  |  240 lines

  1. //    © Paul B. Beeken, Work In Progress, 1994-5
  2. //    Knowledge Software Consulting.
  3. //
  4. //    These files are a mindlessly simple wrapper class for the
  5. //    basic XCMD operations.  Only one instance of the xcmdBase class is
  6. //    generated per XCMD call but there may be many instances of the XCMDString
  7. //    class.  I have used these classes to whip out XCMD/XFCNs within hours of
  8. //    receiving the specs.  They work great for me but I will always consider 
  9. //    suggestions.
  10. //
  11. //    Please, please, please, in the unlikely event you should use this stuff
  12. //    for some commercial application I would appreciate you contacting me.  If
  13. //    its for your own use, use away. Send email: knowsoft@ios.com
  14. //
  15. //    As always: this file is presented as is with no warrantees expressed or implied.
  16. //    Swim at your own risk, etc. etc.
  17. //
  18. //    11/11/95    I've made some simple modifications to this file as well as xcmdString
  19. //        my understanding of c++ has matured and I have made some minor modifications
  20. //        to this implementation to take advantage of a better implementation of xcmdStrings
  21.  
  22. #include    <ctype.h>
  23. #include    "xcmdBase.h"
  24. #include    <Memory.h>
  25. #include    <String.h>
  26.  
  27. // Original notes:
  28. //
  29. //    This file defines all the methods in the base class.
  30. //    Parameters are passed to client functions as zero terminated strings. All the
  31. //    server calls involving strings expect pascal like string arrays. What to do...
  32. //
  33. //    I have just figured out why the parameters passed to this routine are null
  34. //    term strings: The parameters can be arb. long. The input strings, for example,
  35. //    can be the entire contents of a field container. Pascal strings are limited
  36. //    to 255 bytes. So...
  37. //
  38. //    Any server call made by the client, involving a string will expect a "c" like
  39. //    zero terminated string. The member function converts it to a pascal string, places
  40. //    the call, and converts it back on return. This may seem inefficient but "c" strings
  41. //    are more natural for this language and the alg. for conversion is pretty fast. 
  42. //    Besides, most of the time we are not tied up in client requests anyway.
  43. //
  44. //    Here's the problem. For some bizare reason the developers of Hypercard
  45. //    pass zero terminated "C" like strings as parameters in the XCmdPtr.
  46. //    This would be OK by    itself until you realize that most of the callback
  47. //    routines want to see pascal like strings. We have created a special class
  48. //    to handle all the string operations.
  49. //
  50. //    Changes:
  51. //    • xcmdString no longer uses c2pstr and p2cstr.  I devised a simple way to convert
  52. //    from one to another without any calculational overhead (can you guess, no peeking!)
  53. //    • I still don't understand why the call backs needed pascal strings but this is not
  54. //    a problem anymore.
  55.  
  56. #pragma mark    • Creation and Destruction…
  57. //    Creation routine. Registers the XCmdPtr and locks all the parameters high.
  58. //    ____________________________________
  59. xcmdBase::xcmdBase( XCmdPtr xP, Boolean lockParameters ) : 
  60.     paramsLocked( lockParameters )
  61. {
  62.     paramPtr = xP;                //    our copy of the paramPtr
  63.     xcmdString::paramPtr = xP;    // common ptr for xcmdString objects.
  64.     
  65.     //if ( xP )    exitNow = false;  if xp is nil we probably wouldn't be here.
  66.  
  67.         // I don't automaticlly lock the handles to the parameters.
  68.         // if they are small strings then it may needlessly tie up high memory
  69.         // for other things.
  70.     if ( lockParameters )    lockParams();
  71.  
  72. }
  73.  
  74. //    Destruction routine. unlocks all the parameters.
  75. //    ____________________________________
  76. xcmdBase::~xcmdBase( void )
  77. {
  78.     if ( paramsLocked ) unlockParams();
  79. }
  80.  
  81. #pragma mark    -
  82. #pragma mark    • Parameter management…
  83.  
  84. //    Unlocks all the parameters.
  85. //    ____________________________________
  86. void
  87. xcmdBase::unlockParams( void )
  88. {
  89.     if ( paramsLocked ) {
  90.         short i;
  91.  
  92.         for(i=0; i < paramPtr->paramCount; i++) {
  93.             HUnlock(paramPtr->params[i]);
  94.             }
  95.         paramsLocked = false;
  96.         }
  97. }
  98.  
  99. //    Locks all the parameters.
  100. //    ____________________________________
  101. void
  102. xcmdBase::lockParams( void )
  103. {
  104.     if ( !paramsLocked ) {
  105.         short i;
  106.  
  107.         for(i=0; i < paramPtr->paramCount; i++) {
  108.             MoveHHi(paramPtr->params[i]);
  109.             HLock(paramPtr->params[i]);
  110.             }
  111.         paramsLocked = true;
  112.         }
  113. }
  114.  
  115. //    Check the parameter count to see if it is expected.
  116. //    ____________________________________
  117. Boolean
  118. xcmdBase::checkParameters( int min, int max )
  119. {
  120.     if ( paramPtr==nil )    return false;    // no paramPtr so exit
  121.  
  122.     if (max<min) max=min;
  123.  
  124.     if ( nParams() < min ) {
  125.         errorMsg( "too few parameters." );
  126.         return false;
  127.         }
  128.     if ( nParams() > max ) {
  129.         errorMsg( "too many parameters." );
  130.         return false;
  131.         }
  132.     return true;
  133. }
  134.  
  135. //    Array overload. returns the parameter at position i.
  136. //    ____________________________________
  137. Handle
  138. xcmdBase::operator[]( const int i )
  139. {
  140.     if ( i>=0 && i<=16 ) return paramPtr->params[i];
  141.     else return nil;
  142. }
  143.  
  144. short
  145. xcmdBase::scanParams( xcmdString str, short from )
  146. {        // scan all the parameters for key.
  147.     int i;
  148.     xcmdString    p;
  149.  
  150.     for( i=from; i<nParams(); i++ ) {
  151.         p = xcmdString( paramPtr->params[i] );
  152.         if ( p.contains( str ) ) return i;        
  153.         }
  154.     
  155.     return INVALID_INDEX;  // index > 15 is invalid
  156. }
  157.  
  158.  
  159. #pragma mark    -
  160. #pragma mark    • Return code management…
  161.  
  162. //    Return methods. alerts user of error.
  163. //    ____________________________________
  164. void
  165. xcmdBase::errorMsg( xcmdString msg )
  166. {
  167.     returnMsg( "•Error: " & msg );
  168. }
  169.  
  170. //    Return methods. returns string.
  171. //    ____________________________________
  172. void
  173. xcmdBase::returnMsg( xcmdString message )
  174. {
  175.     paramPtr->returnValue = Handle(message);
  176. }
  177.  
  178. #pragma mark    -
  179. #pragma    mark    • Utilities…
  180.  
  181. /****  HyperTalk Utilities  ****/
  182. short
  183. xcmdBase::evalExpr( xcmdString expr, xcmdString* r )
  184. {
  185.     Handle h = EvalExpr( paramPtr, expr );
  186.     xcmdString    rc(h);
  187.     DisposHandle(h);
  188.     if ( r )    // we might not care about a result
  189.         *r = rc;
  190.     return    paramPtr->result;
  191. }
  192.  
  193. short
  194. xcmdBase::sendCardMessage( xcmdString msg )
  195. {
  196.     // message goes to current card.
  197.     SendCardMessage( paramPtr, msg ); 
  198.     return    paramPtr->result;
  199. }
  200.  
  201. short
  202. xcmdBase::sendHCMessage( xcmdString msg )
  203. {
  204.     // message goes to hypercard itself.
  205.     SendHCMessage( paramPtr, msg );
  206.     return    paramPtr->result;
  207. }
  208.  
  209. void
  210. xcmdBase::runScript( xcmdString handler )
  211. {
  212.     RunHandler( paramPtr, handler ); 
  213. }
  214.  
  215. /****  Memory Utilities  ****/
  216. void
  217. xcmdBase::GetGlobal( xcmdString globName, xcmdString* globValue )
  218. {
  219.     Handle        h = ::GetGlobal( paramPtr, globName );
  220.     xcmdString    gv( h );
  221.     DisposHandle( h );
  222.  
  223.     *globValue = gv;
  224. }
  225.  
  226. void
  227. xcmdBase::SetGlobal( xcmdString globName, xcmdString& globValue )
  228. {
  229.     Handle gVal = Handle(globValue); // create a handle of the value
  230.     ::SetGlobal( paramPtr, globName, gVal );
  231.     DisposHandle( gVal );            // dispose of it.
  232. }
  233.  
  234. void
  235. xcmdBase::zeroBytes( Ptr dstPtr, long longCount )
  236. {
  237.     ZeroBytes( paramPtr, dstPtr, longCount ); 
  238. }
  239.  
  240.